package com.supermap.gwfs.message.util;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FTPClientFactory {
    private static Logger logger = LoggerFactory.getLogger(FTPClientFactory.class);

    /**
     * 创建并登陆FTP客户端
     *
     * @param serviceFTP    FTP服务器IP
     * @param loginName     FTP服务器用户名
     * @param loginPassword FTP服务器密码
     * @return
     */
    public static FTPClient loginFTPServer(String serviceFTP, String loginName, String loginPassword) {
        FTPClient ftpClient;
        try {
            ftpClient = new FTPClient();
            FTPClientConfig config = getFTPConfig();
            ftpClient.configure(config);
            ftpClient.connect(serviceFTP);
            ftpClient.login(loginName, loginPassword);
            ftpClient.configure(new FTPClientConfig(ftpClient.getSystemType()));

            // 每次数据连接之前，ftp client告诉ftp server开通一个端口来传输数据
            ftpClient.enterLocalPassiveMode();

            int reply = ftpClient.getReplyCode();
            ftpClient.setDataTimeout(120000);

            if (!FTPReply.isPositiveCompletion(reply)) {
                logger.error("FTPClient Login Failed:PassiveCompletion");
                ftpClient = null;
            }
        } catch (IOException e) {
            logger.error("FTPClient Login Failed:Catch IOException");
            ftpClient = null;
        }
        return ftpClient;
    }

    /**
     * FTP文件上传
     *
     * @param ftpClient      FTP客户端，需要先登陆
     * @param localFilePath  本地文件路径
     * @param remoteFilePath FTP目标文件路径
     * @return
     */
    public static boolean uploadFile(FTPClient ftpClient, String localFilePath, String remoteFilePath) {
        boolean flag;
        InputStream input = null;
        try {
            // 创建ftp目录
            String remotePath = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/"));
            FTPClientFactory.createDirectory(new String(remotePath.getBytes("UTF-8"), "iso-8859-1"), ftpClient);

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
            File file = new File(localFilePath);
            input = new FileInputStream(file);
            flag = ftpClient.storeFile(new String(remoteFilePath.getBytes("UTF-8"), "iso-8859-1"), input);

        } catch (IOException e) {
            logger.error("FTPClient Upload File Failed:Catch IOException");
            flag = false;
        } finally {
            if (input != null)
                try {
                    input.close();
                } catch (IOException e) {
                    logger.warn("FTPClient Upload File Exception:InputStream Can Not Close");
                }
        }
        return flag;
    }

    /**
     * 关闭客户端
     *
     * @param ftpClient
     */
    public static void disconnect(FTPClient ftpClient) {
        if (ftpClient != null) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException e) {
                logger.error("FTPClient Connect Close Failed:Catch IOException");
            }
        }
    }

    /**
     * 设置FTP客服端的配置
     *
     * @return
     */
    private static FTPClientConfig getFTPConfig() {
        FTPClientConfig ftpConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
        ftpConfig.setServerLanguageCode(FTP.DEFAULT_CONTROL_ENCODING);
        return ftpConfig;
    }

    /**
     * 创建远程服务器目录
     *
     * @param remote    远程服务器文件绝对路径
     * @param ftpClient FTP客户端，需要先登陆
     * @return 目录创建是否成功
     */
    private static boolean createDirectory(String remote, FTPClient ftpClient) {
        boolean success = true;
        try {
            if (!ftpClient.changeWorkingDirectory(remote)) {
                // 文件夹不存在,创建目录
                String[] paths = remote.split("/");
                StringBuffer path = new StringBuffer();
                for (String string : paths) {
                    path.append(string + "/");
                    ftpClient.makeDirectory(path.toString());
                }
            }
        } catch (IOException e) {
            logger.error("FTPClient Create Directory Failed:Catch IOException");
            success = false;
        }
        return success;
    }

}
